package org.lord.slark.numbers.activity;

import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import org.lord.slark.numbers.R;
import org.lord.slark.numbers.db.LocalDB;
import org.lord.slark.numbers.entity.Saint;
import org.lord.slark.numbers.utils.ELog;
import org.lord.slark.numbers.utils.LocalConstants;
import org.lord.slark.numbers.utils.SaintsTools;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ChooseSaints extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener {

    private ImageView btnback;
    private TextView btnsave, tvnodata;
    private List<Saint> mList = new ArrayList<Saint>();
    private ListView mListView;
    private SaintAdapter mAdapter;
    private int mRequestID;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        setContentView(R.layout.activity_choose_saints);

        dealWithIntent();
        initView();
        getSaints();
        mAdapter = new SaintAdapter();
        mListView.setAdapter(mAdapter);
    }

    private void dealWithIntent() {
        mRequestID = getIntent().getIntExtra(LocalConstants.REQUESTID, 1);
    }
    private void initView() {
        btnback = (ImageView) findViewById(R.id.btnback);
        btnsave = (TextView) findViewById(R.id.btnsave);
        tvnodata = (TextView) findViewById(R.id.tvnodata);
        mListView = (ListView) findViewById(R.id.listview);
        btnback.setOnClickListener(this);
        btnsave.setOnClickListener(this);
        tvnodata.setOnClickListener(this);
        mListView.setOnItemClickListener(this);
    }

    /**
     * Called when a view has been clicked.
     *
     * @param v The view that was clicked.
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnback:
                onBackPressed();
                break;
            case R.id.btnsave:
                Intent iresult = new Intent();
                iresult.putExtra(LocalConstants.REQUESTID, mRequestID);
                iresult.putExtra(LocalConstants.RESULT_NUMBER, mAdapter.getSelectedCount());
                setResult(RESULT_OK, iresult);
                finish();
                break;
            case R.id.tvnodata:
                Intent iadd = new Intent(this, AddSaintActivity.class);
                startActivity(iadd);
                break;
            default:
                break;
        }
    }

    private void getSaints() {
        mList.clear();
        SQLiteDatabase db = LocalDB.getInstance(this).getWritableDatabase();
        try {
            db.beginTransaction();
            Cursor c = db.query(Saint.TABLE_NAME, null, null, null, null, null, Saint.COLUMN_ID + " asc");
            while (c.moveToNext()) {
                Saint saint = new Saint();
                saint.setName(c.getString(c.getColumnIndex(Saint.COLUMN_NAME)));
                saint.setPhone(c.getString(c.getColumnIndex(Saint.COLUMN_PHONE)));
                saint.setGender(c.getInt(c.getColumnIndex(Saint.COLUMN_GENDER)));
                saint.setIsBaptized(c.getInt(c.getColumnIndex(Saint.COLUMN_IS_BAPTIZED)));
                saint.setId(c.getInt(c.getColumnIndex(Saint.COLUMN_ID)));
                mList.add(saint);
            }
            db.setTransactionSuccessful();
            db.endTransaction();
            c.close();
            SaintsTools.sort(mList);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            db.close();
        }
        if (mList.size() == 0) {
            tvnodata.setVisibility(View.VISIBLE);
        } else {
            tvnodata.setVisibility(View.GONE);
        }
    }

    /**
     * Dispatch onResume() to fragments.  Note that for better inter-operation
     * with older versions of the platform, at the point of this call the
     * fragments attached to the activity are <em>not</em> resumed.  This means
     * that in some cases the previous state may still be saved, not allowing
     * fragment transactions that modify the state.  To correctly interact
     * with fragments in their proper state, you should instead override
     * {@link #onResumeFragments()}.
     */
    @Override
    protected void onResume() {
        super.onResume();
        getSaints();
        mAdapter.notifyDataSetChanged();
    }

    private class SaintAdapter extends BaseAdapter {
        private Map<Integer, Boolean> mSelectedList;
        public SaintAdapter() {
            super();
            mSelectedList = new HashMap<Integer, Boolean>();
        }

        public int getSelectedCount() {
            return mSelectedList.size();
        }

        public void remeberSelected(int position, boolean isChecked) {
            mSelectedList.put(position, isChecked);
        }
        /**
         * How many items are in the data set represented by this Adapter.
         *
         * @return Count of items.
         */
        @Override
        public int getCount() {
            return mList.size();
        }

        /**
         * Get the data item associated with the specified position in the data set.
         *
         * @param position Position of the item whose data we want within the adapter's
         *                 data set.
         * @return The data at the specified position.
         */
        @Override
        public Object getItem(int position) {
            return mList.get(position);
        }

        /**
         * Get the row id associated with the specified position in the list.
         *
         * @param position The position of the item within the adapter's data set whose row id we want.
         * @return The id of the item at the specified position.
         */
        @Override
        public long getItemId(int position) {
            return position;
        }

        /**
         * Get a View that displays the data at the specified position in the data set. You can either
         * create a View manually or inflate it from an XML layout file. When the View is inflated, the
         * parent View (GridView, ListView...) will apply default layout parameters unless you use
         * {@link LayoutInflater#inflate(int, ViewGroup, boolean)}
         * to specify a root view and to prevent attachment to the root.
         *
         * @param position    The position of the item within the adapter's data set of the item whose view
         *                    we want.
         * @param convertView The old view to reuse, if possible. Note: You should check that this view
         *                    is non-null and of an appropriate type before using. If it is not possible to convert
         *                    this view to display the correct data, this method can create a new view.
         *                    Heterogeneous lists can specify their number of view types, so that this View is
         *                    always of the right type (see {@link #getViewTypeCount()} and
         *                    {@link #getItemViewType(int)}).
         * @param parent      The parent that this view will eventually be attached to
         * @return A View corresponding to the data at the specified position.
         */
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = LayoutInflater.from(ChooseSaints.this).inflate(R.layout.choose_saints_list_item, null);
                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
                holder.name = (TextView) convertView.findViewById(R.id.name);
                holder.gender = (TextView) convertView.findViewById(R.id.gender);
                holder.checkbox = (CheckBox) convertView.findViewById(R.id.checkbox);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            Saint saint = mList.get(position);
            ELog.d("xsdebug", "list item name:"+saint.getName()+", gender:"+saint.getGender());
            holder.icon.setImageResource(R.mipmap.star_icon);
            holder.name.setText(saint.getName());
            holder.gender.setText(getString(saint.getGender() == 1 ? R.string.sbro : R.string.ssis));
            holder.checkbox.setChecked(mSelectedList.get(position) == null ? false : mSelectedList.get(position));
            return convertView;
        }
    }

    private static class ViewHolder {
        ImageView icon;
        TextView name;
        TextView gender;
        CheckBox checkbox;
    }

    /**
     * Callback method to be invoked when an item in this AdapterView has
     * been clicked.
     * <p/>
     * Implementers can call getItemAtPosition(position) if they need
     * to access the data associated with the selected item.
     *
     * @param parent   The AdapterView where the click happened.
     * @param view     The view within the AdapterView that was clicked (this
     *                 will be a view provided by the adapter)
     * @param position The position of the view in the adapter.
     * @param id       The row id of the item that was clicked.
     */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        CheckBox cb = (CheckBox) view.findViewById(R.id.checkbox);
        if (cb != null) {
            cb.toggle();
            mAdapter.remeberSelected(position, cb.isChecked());
        }
    }
}
